package com.noble.glamour.module.invoke;

import android.app.Activity;
import android.support.v4.app.FragmentActivity;

import com.alibaba.fastjson.JSON;
import com.noble.glamour.application.App;
import com.noble.glamour.module.baseui.dialog.loading.LoadingDialog;
import com.noble.library.helper.ChineseFilter;
import com.noble.library.observe.MsgMgr;
import com.noble.library.tools.PLogger;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * CMD操作统一处理
 */
public class Invoker {

    // js cmd key
    public static final String JSCMD_refresh_web = "refresh_web";//主动调用刷新web页面
    public static final String JSCMD_ranking_btn_click = "ranking_btn_click";// 风云榜按钮点击事件（本周上周切换）
    public static final String JSCMD_header_right_btn_click = "header_right_btn_click";// 导航条右侧按钮点击事件
    public static final String JSCMD_turntable_result = "turntable_result";// 转盘转动结果(同步他人客户端开始抽奖)
    public static final String JSCMD_chat_message = "chat_message";// 聊天信息
    public static final String JSCMD_gift_message = "gift_message";// 礼物信息
    public static final String JSCMD_turntable_activity = "turntable_activity";//启动关闭转盘
    public static final String JSCMD_warning_message = "warning_message";//视频警告消息

    private WebAppInterface appInterface = new WebAppInterface(App.context, null);
    private Object webView;

    /**
     * @return 获取持有的WebAppInterface实例
     */
    public WebAppInterface getWebAppInterface() {
        return appInterface;
    }

    //--------------------CMD处理start--------------------

    private static class SingletonHolder {
        public static Invoker instance = new Invoker();
    }

    public static Invoker getInstance() {
        return SingletonHolder.instance;
    }

    private Invoke invoke = new Invoke();

    /**
     * 根据command和data执行对应方法（处理在app内情况）
     *
     * @param appInterface WebAppInterface实例
     * @param cmd          CMD操作码
     * @param data         操作执行的json字符串数据
     */
    public void doInApp(WebAppInterface appInterface, final String cmd, final String data) {
        PLogger.d("---doInApp--->cmd：" + cmd + "，data：" + data +
                "，AppMgr.isForground()：" + App.isForeground());

        this.appInterface = (appInterface == null ? new WebAppInterface(App.context, null) : appInterface);
        webView = appInterface == null ? null : appInterface.getWebView();

        MsgMgr.getInstance().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Method notifyCMDMethod = Invoke.class.getMethod(cmd, String.class);
                    notifyCMDMethod.invoke(invoke, data);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 本地调用执行JS逻辑
     *
     * @param cmd  JS cmd命令
     * @param data 传递给JS的数据
     */
    public void doInJS(String cmd, Map<String, Object> data) {
        Map<String, Object> cmdMap = new HashMap<>();
        cmdMap.put("jcmd", cmd);
        cmdMap.put("data", data == null ? new HashMap<>() : data);
        String url = "javascript:window.platform.appCommand('" + JSON.toJSONString(cmdMap) + "')";
        doInJS(url);
    }

    /**
     * 本地调用执行JS逻辑：特殊情况主动调用，如base64图片传输，无需转码
     *
     * @param callbackName   回调方法名
     * @param callbackID     回调id
     * @param responseString 调用传值
     * @param isTranscode    是否进行字符串转码
     */
    public void doInJS(final String callbackName, final String callbackID, final String responseString, final boolean isTranscode) {
        Flowable.create(new FlowableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull FlowableEmitter<String> e) throws Exception {
                e.onNext(isTranscode ? ChineseFilter.toUnicode(responseString) : responseString);
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io()).
                observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                doInJS("javascript:" + callbackName + "(\'" + callbackID + "\',\'" + s + "\')");
            }
        });
    }

    /**
     * 本地调用执行JS逻辑，默认进行字符串转码，以支持中文字符串的传输
     *
     * @param callbackName   回调方法名
     * @param callbackID     回调id
     * @param responseString 是否进行字符串转码
     */
    public void doInJS(String callbackName, String callbackID, String responseString) {
        doInJS(callbackName, callbackID, responseString, true);
    }

    /**
     * 本地调用执行JS逻辑
     *
     * @param loadUrl 调用执行的命令
     */
    public void doInJS(String loadUrl) {
        if (webView != null) {
            if (webView instanceof com.tencent.smtt.sdk.WebView) {
                ((com.tencent.smtt.sdk.WebView) webView).loadUrl(loadUrl);
                PLogger.d("---tencent x5--->" + loadUrl);
            } else if (webView instanceof android.webkit.WebView) {
                ((android.webkit.WebView) webView).loadUrl(loadUrl);
                PLogger.d("---webkit--->" + loadUrl);
            }
        }
    }

    /**
     * 设置webView，每次webView页面可见的时候重设
     *
     * @param webView WebView实例
     */
    public void setWebView(Object webView) {
        this.webView = webView;
        PLogger.d("------>" + String.valueOf(webView));
    }

    //--------------------CMD处理end--------------------

    public class Invoke {

        // 显示加载loading
        public void show_data_loading(String data) {
            PLogger.d("show_data_loading: ------>" + data);
            Activity act = appInterface.getAct();
            LoadingDialog.show((FragmentActivity) (act == null ? App.getActivity() : act));
        }

        // 关闭加载loading
        public void hide_data_loading(String data) {
            PLogger.d("hide_data_loading: ------>" + data);
            LoadingDialog.closeLoadingDialog(500);
        }
    }


    // --------------------------- JSCMD ----------------------------

    /**
     * JSCMD： 女用户转盘自动旋转结果
     */
    public void rotaryResultJSCMD(final int result) {
        App.activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Map<String, Object> data = new HashMap<>();
                data.put("index", result);
                doInJS(Invoker.JSCMD_turntable_result, data);
            }
        });
    }
}
